#ifndef __SHMIPC_COM_UDS_SERVER_H__
#define __SHMIPC_COM_UDS_SERVER_H__

#include <cstdint>
#include <string>
#include <functional>
#include <map>
#include <atomic>
#include <mutex>

#include "shmipc/core/xresult.h"
#include "shmipc/core/xthread.h"
#include "shmipc/com/com_types.h"
#include "shmipc/com/xmessage.h"
#include "shmipc/com/xmessage_allocator.h"
#include "shmipc/com/internal/uds_session.h"

namespace shmipc::com {

class UdsServer: virtual public XMessageAllocator {
public:
    using OnConnectStatusHandler = std::function<void(XComId client_id, bool is_connected)>;
    using OnMessageHandler = std::function<void(XMessageSp msg)>;
    using IoWorker = std::unique_ptr<core::XThread>;
    using SessionMap = std::map<XComId, internal::UdsSessionSp>;
public:
    UdsServer();
    virtual ~UdsServer();

public:
    virtual core::XResultCode bind(const std::string& url, OnConnectStatusHandler on_handler = nullptr);
    virtual core::XResultCode unbind();
public:
    virtual void setOnMessageHandler(OnMessageHandler on_msg_handler); /** is set this ,then 'OnMessage(XMessageSp msg);' will be overrid */
    virtual core::XResultCode send(XMessageSp msg);

public:
    virtual core::XResult<XMessageSp> allocResponse(XMessageSp request, uint32_t payload_size, uint8_t* payload = nullptr);

protected:
    virtual void onListener();
    virtual void onReceiver();
    virtual void onMessage(XMessageSp msg);
protected:
    virtual void addClient(XComId client_id);
    virtual void delClient(XComId client_id);
    virtual void delSessions();
protected:
    std::atomic_uint16_t next_seq_num_ = 0;
    bool is_connected_ = false;
    bool is_running_ = false;
    XComId uds_fd_ = XBUS_INVALID_XCOM_ID;
    std::string url_;
    
    IoWorker recv_worker_ = nullptr;
    IoWorker listener_worker_ = nullptr;
    XMessageQueueSp recv_queue_ = nullptr;
    OnMessageHandler on_message_handler_;
    OnConnectStatusHandler on_connect_status_;
    SessionMap sessions_;
    SessionMap deleted_sessions_;
    std::mutex lock_;
};


} //namespace shmipc::com

#endif /** !__SHMIPC_COM_UDS_SERVER_H__ */
